iT邦幫忙

2024 iThome 鐵人賽

DAY 13
1
JavaScript

30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能系列 第 13

第 13 天:2024 年 JavaScript 新特性 - 性能優化

  • 分享至 

  • xImage
  •  

新的性能優化工具和API


參考文章:今晚,我想來點 Web 前端效能優化大補帖

這部分內容包括 JavaScript 和瀏覽器中近期引入的性能優化工具和 API,這些新特性主要幫助開發者提升代碼的執行效率和加載速度。主要的新特性可能包括:

  1. Performance API:用於測量和分析代碼性能的 API。例如,performance.now() 提供高精度的時間戳,用於性能測試。
  2. WebAssembly:將性能密集型計算移到 WebAssembly 模塊,從而提高效率。
  3. Service Workers:支持在背景中運行腳本,提升網站的離線體驗和加載速度。
  4. Worklets:提供更靈活的多執行緒支持,用於處理高性能計算和 UI 渲染。
  5. Lazy Loading 和 Dynamic Import:優化資源加載,僅在需要時加載模塊或資源,從而提升初始加載速度。
  6. Web Vitals API:測量用戶體驗的關鍵指標,如 Largest Contentful Paint (LCP) 和 Cumulative Layout Shift (CLS),幫助改善網站性能。

Performance.mark()Performance.measure() 的擴展


MDN文件:Performance.mark()Performance.measure()

功能
Performance.mark()Performance.measure() 是 Web Performance API 的一部分,用於標記和測量程式碼執行時間,2024 年的擴展使得這些方法更加靈活和精確。

mark() 方法在瀏覽器的效能緩衝區中使用給定名稱新增一個 timestamp(時間戳)。

measure() 方法在瀏覽器效能記錄快取中建立了一個名為時間戳記的記錄來記錄兩個特殊標誌位元(通常稱為開始標誌和結束標誌)。

優點
這些方法可以用於精確測量程式碼區塊的效能,幫助開發者分析執行時間和最佳化效能。

performance.mark('start');

// do somthing...

performance.mark('end');
performance.measure('My Measurement', 'start', 'end');

const measures = performance.getEntriesByName('My Measurement');
console.log(measures);

performance.mark-console.log

SharedArrayBufferAtomics 的改進


MDN:SharedArrayBufferAtomics
參考文章:SharedArrayBuffer和Atomics是什么

功能
一直以來 Javascript 都是單線程的,因為在運行時頁面是不能響應用戶的交互的,因此如果運行時間較長,用戶就會感覺頁面卡死了,使用者體驗下降,慢慢造訪的人就會降低;
SharedArrayBufferAtomics 的改進使得在多執行緒環境中對共享記憶體的操作更有效率。

SharedArrayBuffer 是一種新的記憶體類型,可以在多個線程之間共享,允許多個執行緒直接存取相同的記憶體區域,從而實現共享資料的功能。

Atomics 是一個全域對象,它提供了一組原子操作的方法,用於在多個線程之間安全地讀寫 SharedArrayBuffer 中的記憶體。

優點
改進後的 API 提供了更有效率的同步和通訊方式,適合併發程式設計和效能最佳化。

const sharedBuffer = new SharedArrayBuffer(1024);
const int32Array = new Int32Array(sharedBuffer);

Atomics.store(int32Array, 0, 42);
console.log(Atomics.load(int32Array, 0));

性能測試和改進


這部分內容關注於如何測試和改進代碼的性能,包括:

  1. 性能測試工具:

    • Lighthouse:Google 提供的工具,用於測量網站的性能、SEO、可及性等。
    • WebPageTest:用於測試網站在不同地區和設備上的加載速度。
    • Chrome DevTools:提供多種性能分析工具,如 Performance 面板、Memory 面板等。
      性能分析和診斷:
  2. 內存分析:識別內存泄漏和過度使用的情況。

    • CPU 分析:了解代碼的 CPU 使用情況,識別性能瓶頸。
    • 網絡分析:測試和優化網絡請求的加載時間和帶寬使用。
    • 性能改進策略:
  3. 減少重排和重繪:優化 DOM 操作,減少不必要的重排和重繪。

    • 代碼拆分:使用代碼拆分技術,如 Webpack 的 code-splitting,按需加載代碼。
    • 優化圖片和資源:使用合適的格式和壓縮工具來優化圖片和其他靜態資源。

      🔔 推薦壓縮圖片檔的網站:
      Smart WebP, PNG and JPEG Compression for Faster Websites

    • 減少 JavaScript 的執行時間:優化代碼,避免長時間的執行和複雜的計算。

🤔 這麼多內容,到底怎麼做才有點優化的效果呢?
以下是實戰以來有遇到後改變寫法提升效能的範例,雖然最後多半還是靠後端 api 速度提升,前端減少呼叫才讓使用者體感變好!

  1. 減少 DOM 操作:盡量減少存取和操作 DOM 的次數,因為很慢

    // 原來寫法
    document.getElementById('myElement').style.color = 'gold';
    document.getElementById('myElement').style.backgroundColor = 'black';
    
    // 建議寫法
    const element = document.getElementById('myElement');
    element.style.color = 'gold';
    element.style.backgroundColor = 'black';
    
  2. 使用高效率的循環結構:當效能至關重要時,優先選擇「for」迴圈或是用高階函數

    const arr = [1, 2, 3, 4, 5];
    
    // 原來寫法
    for (let i in arr) {
        console.log(arr[i]);
    }
    
    // 建議寫法
    for (let i = 0; i < arr.length; i++) {
        console.log(arr[i]);
    }
    
  3. 避免不必要的函數呼叫

    // 原來寫法
    function getSquare(num) {
        return num * num;
    }
    
    for (let i = 0; i < 1000; i++) {
        const square = getSquare(i);
    }
    
    // 建議寫法
    for (let i = 0; i < 1000; i++) {
        const square = i * i;
    }
    
  4. 使用適當的資料結構:在適用的情況下使用映射、集合和類型化陣列 -> 這個在套件中要轉成顯示的架構用過,之後鮮少使用

    const map = new Map();
    map.set('key', 'value');
    console.log(map, map.get('key'))   // Map(1) {'key' => 'value'}  'value'
    
  5. Debounce and Throttle
    Debounce:如果多次點擊按鈕,就有可能出現無回應的情況,並且會出現過多的請求 API 呼叫,去抖動是一種程式設計實踐,確保某些任務不會過於頻繁地觸發。
    Debounce

    <button type="submit" id="debounce">submit</button>
    
    const debounce = (fn, delay) => {
        let timeoutID;
    
        return function (...args) {
            if (timeoutID) {
                clearTimeout(timeoutID);
            }
    
            timeoutID = setTimeout(() => {
                fn(...args);
            }, delay);
        }
    }
    
    document.getElementById('debounce').addEventListener('click',
        debounce((e) => {
            console.count('debounce_click');
        }, 2000)
    );
    

    Throttle:當第一次單擊按鈕時,它將執行操作,如果繼續單擊該按鈕,直到時間間隔過去,它才會觸發事件,如果繼續單擊它會在每次完成間隔時觸發。
    Throttle

    <button type="submit" id="throttle">submit</button>
    
    const throttle = (fn, delay) => {
        let last = 0;
    
        return (...args) => {
            const now = new Date();
            if (now - last < delay) return;
    
            last = now;
    
            return fn(...args)
        }
    }
    
    document.getElementById('throttle').addEventListener('click',
        throttle((e) => {
            console.count('throttle_click');
        }, 2000)
    );
    

    Debounce and Throttle - kuku
    如果圖片太模糊,可以到 YT 看錄製的 透過 console.log 認識 Debounce and Throttle 13 秒影片唷!我嘗試多種轉檔,畫面如果真的不行,首先還是謝謝您的觀賞,但是也請告訴我,一起想辦法吧!感謝您!


上一篇
第 12 天:2024 年 JavaScript 新特性 - 方法
下一篇
第 14 天:2024 年 JavaScript 新特性 - 類型檢查
系列文
30天 JavaScript 提升計畫:從零到精通結合2024年的創新功能30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言